package com.runfast.waimai.web.controller;

import com.runfast.common.dao.model.RunfastCuseraddress;
import com.runfast.common.service.RunfastCuseraddressService;
import com.runfast.common.utils.TokenUtil;
import com.runfast.common.web.entity.Result;
import com.runfast.common.web.entity.ResultCode;
import com.runfast.paotui.entity.DeliveryCost;
import com.runfast.waimai.common.Constants;
import com.runfast.waimai.dao.model.*;
import com.runfast.waimai.entity.CartItem;
import com.runfast.waimai.entity.CartItemKey;
import com.runfast.waimai.entity.OptionIdPair;
import com.runfast.waimai.service.*;
import com.runfast.waimai.web.dto.GoodsStandarDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.comparator.ComparableComparator;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 商品购物车接口
 */
@RestController("userWmCartController")
@RequestMapping(value = "/api/user/wm/cart", headers = "token")
public class CartController {

    @Resource
    private RedisTemplate redisTemplate;

    @Autowired
    private RunfastShoppingtrolleyService shoppingtrolleyService;

    @Autowired
    private RunfastGoodsSellStandardService standardService;

    @Autowired
    private RunfastGoodsSellOptionService optionService;

    @Autowired
    private RunfastGoodsSellSubOptionService subOptionService;

    @Autowired
    private RunfastGoodsSellService goodsSellService;

    @Autowired
    private RunfastActivityService activityService;

    @Autowired
    private RunfastActivityTargetService activityTargetService;

    @Autowired
    private RunfastBusinessService businessService;

    @Autowired
    private RunfastFullLessService fullLessService;

    @Autowired
    private RunfastGoodsSellRecordService goodsSellRecordService;





    /**
     * 获取用户在商家下添加的购物车列表
     *
     * @param businessId 商户id
     * @param token
     * @return
     */
    @PostMapping("/list")
    public Result<Collection<CartItem>> list(@RequestParam int businessId, @RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);

        RunfastBusiness business = businessService.selectByPrimaryKey(businessId);
        if (business == null) return Result.fail(ResultCode.BUSINESS_NOT_EXIST);

        HashOperations hashOperations = redisTemplate.opsForHash();
        HashMap<CartItemKey, CartItem> cartMap = (HashMap<CartItemKey, CartItem>) hashOperations.get(Constants.REDIS_NAMESPACE_CART + userId, businessId);
        if (cartMap == null) cartMap = new HashMap<>();
        return Result.ok("", cartMap.values());
    }

    /**
     * 保存购物车
     *
     * @param cart  [{"key":{"standarId":1,"optionIdPairList":[{"optionId":1,"subOptionId":2}]}, "num":5}]
     * @param token
     * @return
     */
    @PostMapping("/save")
    public Result<Collection<CartItem>> save(@RequestParam Integer businessId, @RequestBody List<CartItem> cart, @RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);

        RunfastBusiness business = businessService.selectByPrimaryKey(businessId);
        if (business == null) return Result.fail(ResultCode.BUSINESS_NOT_EXIST);


        /**
         * 校验参数
         */

        Map<CartItemKey, CartItem> cartMap = new HashMap<>();
        List<Integer> standarIdList = new ArrayList<>();
        for (CartItem cartItem : cart) {


            Integer num = cartItem.getNum();
            if (num == null || num < 1) return Result.fail(ResultCode.FAIL, "数量必须大于0");

            CartItemKey key = cartItem.getKey();
            Integer goodsId = key.getGoodsId();
            if (goodsId == null) return Result.fail(ResultCode.FAIL, "商品id不能为null");
            Integer standarId = key.getStandarId();
            if (standarId == null) return Result.fail(ResultCode.FAIL, "必须选择规格");
            standarIdList.add(standarId);

            List<RunfastGoodsSell> goodsWithStandar = goodsSellService.findGoodsWithStandar(goodsId, cart);
            if (goodsWithStandar.size() != standarIdList.size()) {
                return Result.fail(ResultCode.STANDARD_NOT_EXIST, "该商品已修改,请重新下单");
            }

            List<OptionIdPair> optionIdPairListForCheck = key.getOptionIdPairList();

            List<Integer> optionIdListForCheck = new ArrayList<>();
            List<Integer> subOptionIdListForCheck = new ArrayList<>();
            if (optionIdPairListForCheck != null && !optionIdPairListForCheck.isEmpty()) {
                for (OptionIdPair pair : optionIdPairListForCheck) {
                    if (pair.getOptionId() != null) {
                        optionIdListForCheck.add(pair.getOptionId());
                    } else {
                        return Result.fail(ResultCode.FAIL, "属性不能为null");
                    }
                    if (pair.getSubOptionId() != null) {
                        subOptionIdListForCheck.add(pair.getSubOptionId());
                    } else {
                        return Result.fail(ResultCode.FAIL, "子选项不能为null");
                    }
                }
            }


            CartItemKey cartItemKey = new CartItemKey();
            cartItemKey.setGoodsId(goodsId);
            cartItemKey.setStandarId(standarId);


            /**
             * 设置属性
             */
            List<RunfastGoodsSellOption> optionWithSub = optionService.findOptionWithSub(goodsId);

            if (!optionWithSub.isEmpty()) {
                // 如果该商品有属性
                if (optionWithSub.size() == subOptionIdListForCheck.size()) {//每个属性都指定了一个子项

                    List<OptionIdPair> optionIdPairList = optionService.checkSubOptionIds(goodsId, optionIdListForCheck, subOptionIdListForCheck);
                    if (optionIdPairList.size() != optionWithSub.size())
                        return Result.fail(ResultCode.SUB_OPTION_NOT_EXIST, "该商品已修改,请重新下单");
                    //设置最终合法的属性
                    cartItemKey.setOptionIdPairList(optionIdPairList);
                } else {
                    return Result.fail(ResultCode.SUB_OPTION_NOT_EXIST, "该商品已修改,请重新下单");

                }
            }


            cartMap.put(cartItemKey, cartItem);

        }


        /**
         * 参数没问题，清空购物车
         */
        String cartKey = Constants.REDIS_NAMESPACE_CART + userId;
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.delete(cartKey, businessId);

        //保存至redis
        hashOperations.put(cartKey, businessId, cartMap);

        return Result.ok("");
    }



    /**
     * 添加购物车
     *
     * @param token
     * @return
     */
    @PostMapping("/add")
    public Result<Collection<CartItem>> add(@RequestParam Integer standarId, @RequestParam(required = false) Integer[] subOptionIds, @RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);

        RunfastGoodsSellStandard goodsSellStandard = standardService.selectByPrimaryKey(standarId);
        if (goodsSellStandard == null) return Result.fail(ResultCode.STANDARD_NOT_EXIST, "该规格不存在,请重新手动添加");
        Integer goodsSellId = goodsSellStandard.getGoodsSellId();
        RunfastGoodsSell goodsSell = goodsSellService.selectByPrimaryKey(goodsSellId);
        if (goodsSell == null) return Result.fail(ResultCode.GOODS_NOT_EXIST, "该商品不存在,请重新手动添加");


        String cartKey = Constants.REDIS_NAMESPACE_CART + userId;


        HashOperations hashOperations = redisTemplate.opsForHash();
        Map<CartItemKey, CartItem> cartMap = (HashMap<CartItemKey, CartItem>) hashOperations.get(cartKey, goodsSellStandard.getBusinessId());

        CartItemKey cartItemKey = new CartItemKey();
        cartItemKey.setStandarId(standarId);


        /**
         * 设置属性
         */
        List<RunfastGoodsSellOption> optionWithSub = optionService.findOptionWithSub(goodsSellId);

        if (!optionWithSub.isEmpty()) {
            // 如果该商品有属性
            if (optionWithSub.size() == subOptionIds.length) {

                List<Integer> subOptionIdList = (List<Integer>) CollectionUtils.arrayToList(subOptionIds);


//                List<OptionIdPair> optionIdPairList = optionService.checkSubOptionIds(goodsSellId, subOptionIdList);
                List<OptionIdPair> optionIdPairList = null;
                if (optionIdPairList.size() != optionWithSub.size())

                    return Result.fail(ResultCode.SUB_OPTION_NOT_EXIST, "非法子选项参数");

                cartItemKey.setOptionIdPairList(optionIdPairList);


            } else {
                return Result.fail(ResultCode.SUB_OPTION_NOT_EXIST, "非法子选项参数");

            }
        }

        /**
         * 计算是否该增长num还是添加新cart item
         */
        if (cartMap != null) {
            CartItem cartItem = cartMap.get(cartItemKey);
            if (cartItem == null) {

                cartItem = new CartItem();
                cartItem.setKey(cartItemKey);
                cartItem.setNum(1);
                cartMap.put(cartItemKey, cartItem);
            } else {
                Integer num = cartItem.getNum();
                num++;
                cartItem.setNum(num);
                cartMap.put(cartItemKey, cartItem);
            }

        } else {
            cartMap = new HashMap<>();
            CartItem cartItem = new CartItem();
            cartItem.setKey(cartItemKey);
            cartItem.setNum(1);
            cartMap.put(cartItemKey, cartItem);

        }
        //保存至redis
        hashOperations.put(cartKey, goodsSellStandard.getBusinessId(), cartMap);

        return Result.ok("", cartMap.values());

    }

    /**
     * 删除购物车商品
     *
     * @param token
     * @return
     */
    @PostMapping("/delete")
    public Result delete(@RequestParam Integer standarId, @RequestParam(required = false) Integer[] subOptionIds, @RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);

        RunfastGoodsSellStandard goodsSellStandard = standardService.selectByPrimaryKey(standarId);
        if (goodsSellStandard == null) return Result.fail(ResultCode.STANDARD_NOT_EXIST, "该规格不存在,请重新手动添加");
        Integer goodsSellId = goodsSellStandard.getGoodsSellId();
        RunfastGoodsSell goodsSell = goodsSellService.selectByPrimaryKey(goodsSellId);
        if (goodsSell == null) return Result.fail(ResultCode.GOODS_NOT_EXIST, "该商品不存在,请重新手动添加");


        //构造购物车item的key
        CartItemKey cartItemKey = new CartItemKey();
        cartItemKey.setStandarId(standarId);

        /**
         * 设置属性
         */
        List<RunfastGoodsSellOption> optionWithSub = optionService.findOptionWithSub(goodsSellId);

        if (!optionWithSub.isEmpty()) {
            // 如果该商品有属性
            if (optionWithSub.size() == subOptionIds.length) {

                List<Integer> subOptionIdList = (List<Integer>) CollectionUtils.arrayToList(subOptionIds);


//                List<OptionIdPair> optionIdPairList = optionService.checkSubOptionIds(goodsSellId, subOptionIdList);
//                if (optionIdPairList.size() != optionWithSub.size())
                return Result.fail(ResultCode.SUB_OPTION_NOT_EXIST, "非法子选项参数");

//                cartItemKey.setOptionIdPairList(optionIdPairList);


            } else {
                return Result.fail(ResultCode.SUB_OPTION_NOT_EXIST, "非法子选项参数");

            }
        }

        Map<CartItemKey, CartItem> cartMap = null;
        String cartKey = Constants.REDIS_NAMESPACE_CART + userId;
        HashOperations hashOperations = redisTemplate.opsForHash();
        cartMap = (HashMap<CartItemKey, CartItem>) hashOperations.get(cartKey, goodsSellStandard.getBusinessId());

        /**
         * 计算是否该减num还是删除cart item
         */
        if (cartMap != null) {
            CartItem cartItem = cartMap.get(cartItemKey);
            if (cartItem == null) {
                return Result.fail(ResultCode.FAIL, "购物车中不存在该购物信息");
            } else {
                Integer num = cartItem.getNum();
                if (num == 1) {
                    cartMap.remove(cartItemKey);
                } else if (num > 1) {

                    num--;
                    cartItem.setNum(num);
                    cartMap.put(cartItemKey, cartItem);
                }

            }

        } else {
            return Result.fail(ResultCode.FAIL, "购物车中不存在该购物信息");

        }
        //购物车数据同步至redis
        hashOperations.put(cartKey, goodsSellStandard.getBusinessId(), cartMap);

        return Result.ok("", cartMap.values());
    }

    /**
     * 清空购物车
     *
     * @param businessId 商户id
     * @param token
     * @return
     */
    @PostMapping("/clear")
    public Result clear(@RequestParam int businessId, @RequestHeader String token) {
        Integer userId = TokenUtil.getUserId(token);

        String cartKey = Constants.REDIS_NAMESPACE_CART + userId;
        HashOperations hashOperations = redisTemplate.opsForHash();
        Long delete = hashOperations.delete(cartKey, businessId);
        return Result.ok("");
    }

}
